package com.zzedu.framework.security;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Sets;
import com.zzedu.common.core.domain.entity.SysUser;
import com.zzedu.common.enums.CommonEnums;
import com.zzedu.common.enums.UserTypeEnumns;
import com.zzedu.common.utils.StringUtils;
import com.zzedu.common.utils.security.LoginUser;
import com.zzedu.common.utils.spring.SpringUtils;
import com.zzedu.domain.ZzSchool;
import com.zzedu.domain.ZzStudent;
import com.zzedu.domain.ZzTeacher;
import com.zzedu.framework.web.domain.LoginForm;
import com.zzedu.framework.web.service.CustomPasswordService;
import com.zzedu.framework.web.service.ISysPermissionService;
import com.zzedu.framework.web.service.SysLoginService;
import com.zzedu.framework.web.service.SysPasswordService;
import com.zzedu.mapper.ZzSchoolMapper;
import com.zzedu.mapper.ZzStudentMapper;
import com.zzedu.mapper.ZzTeacherMapper;
import com.zzedu.system.service.ISysMenuService;
import com.zzedu.system.service.ISysRoleService;
import com.zzedu.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;

@Component
public class MyUserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private ISysMenuService menuService;
    @Autowired
    private ISysRoleService roleService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private SysLoginService sysLoginService;

    @Autowired
    private SysPasswordService passwordService;
    @Autowired
    private ISysPermissionService permissionService;


    @Autowired
    private ZzStudentMapper zzStudentMapper;

    @Autowired
    private ZzTeacherMapper zzTeacherMapper;

    @Autowired
    private ZzSchoolMapper zzSchoolMapper;

    @Override
    public UserDetails loadUserByUsername(String loginBodyJson) throws UsernameNotFoundException {
        try {
            LoginForm loginForm = JSON.parseObject(loginBodyJson, LoginForm.class);
            //自定义密码验证器
            CustomPasswordService customPasswordService = null;
            if (null != loginForm.getLoginType() && StringUtils.isNotBlank(loginForm.getLoginType().getCheckValidator())) {
                customPasswordService = SpringUtils.getBean(loginForm.getLoginType().getCheckValidator());
            }
            UserTypeEnumns loginUserTypeEnumns = loginForm.getUserTypeEnumns();
            if (UserTypeEnumns.PLATFORM == loginUserTypeEnumns) {
                SysUser user = sysLoginService.login(loginForm);
                if (null != user) {
                    if (null == customPasswordService) {
                        passwordService.validate(user, loginForm.getPassword());
                    } else {
                        customPasswordService.validate(user, loginForm);
                    }
                    sysLoginService.recordLoginInfo(user.getId());
                    HashSet<GrantedAuthority> authorities = Sets.newHashSet();
                    // 角色列表
                    Set<String> roles = roleService.selectRolePermissionByUserId(user.getId());
                    // 功能列表
                    Set<String> permissions = menuService.selectMenuPermsByUserId(user.getId());
                    if (user.isAdmin()) {
                        permissions.add(PermissionService.ALL_PERMISSION);
                    }
                    for (String role : roles) {
                        authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
                    }
                    for (String permission : permissions) {
                        authorities.add(new SimpleGrantedAuthority(permission));
                    }
                    return createLoginUser(user, authorities);
                }
            } else if (UserTypeEnumns.STUDENT == loginUserTypeEnumns) {
                //学生登录
                ZzStudent zzStudent = zzStudentMapper.selectOne(Wrappers.lambdaQuery(ZzStudent.class).eq(ZzStudent::getTel, loginForm.getUsername()).last("limit 1"));
                if (null != zzStudent) {
                    if (CommonEnums.NO == CommonEnums.getCode(zzStudent.getState())) {
                        throw new DisabledException("学生状态有误,不能使用");
                    }

                    //验证学校
                    ZzSchool zzSchool = zzSchoolMapper.selectById(zzStudent.getSchoolId());
                    if (null == zzSchool) {
                        throw new DisabledException("对应学校不存在");
                    }
                    if (zzSchool.getState() == 2) {
                        throw new DisabledException("当前校区已停用");
                    }

                    zzStudentMapper.update(Wrappers.lambdaUpdate(ZzStudent.class)
                            .set(ZzStudent::getLastLoginDate, LocalDateTime.now())
                            .eq(ZzStudent::getId, zzStudent.getId()));
                    SysUser user = new SysUser();
                    user.setId(zzStudent.getId());
                    user.setUserName(zzStudent.getTel());
                    user.setNickName(zzStudent.getStuName());
                    user.setPassword(zzStudent.getPwd());
                    user.setUserType(UserTypeEnumns.STUDENT.getCode());
                    user.setAvatar(null == zzStudent.getAvatar() ? null : zzStudent.getAvatar() + "");
                    user.setSex(zzStudent.getStuSex() + "");
                    if (null == customPasswordService) {
                        passwordService.validate(user, loginForm.getPassword());
                    } else {
                        customPasswordService.validate(user, loginForm);
                    }
                    return createLoginUser(user, Sets.newHashSet());
                }
                //老师登录
                ZzTeacher zzTeacher = zzTeacherMapper.selectOne(Wrappers.lambdaQuery(ZzTeacher.class).eq(ZzTeacher::getTel, loginForm.getUsername()).last("limit 1"));
                if (null != zzTeacher) {
                    if (CommonEnums.NO == CommonEnums.getCode(zzTeacher.getState())) {
                        throw new DisabledException("老师状态有误,不能使用");
                    }
                    //验证学校
                    ZzSchool zzSchool = zzSchoolMapper.selectById(zzTeacher.getSchoolId());
                    if (null == zzSchool) {
                        throw new DisabledException("对应学校不存在");
                    }
                    if (zzSchool.getState() == 2) {
                        throw new DisabledException("当前校区已停用");
                    }
                    SysUser user = new SysUser();
                    user.setId(zzTeacher.getId());
                    user.setUserName(zzTeacher.getTel());
                    user.setNickName(zzTeacher.getName());
                    user.setPassword(zzTeacher.getPwd());
                    user.setUserType(UserTypeEnumns.DEVICE_TEACHER.getCode());
                    if (null == customPasswordService) {
                        passwordService.validate(user, loginForm.getPassword());
                    } else {
                        customPasswordService.validate(user, loginForm);
                    }
                    return createLoginUser(user, Sets.newHashSet());
                }

            } else if (UserTypeEnumns.DEVICE_TEACHER == loginUserTypeEnumns) {
                //老师登录
                ZzTeacher zzTeacher = zzTeacherMapper.selectOne(Wrappers.lambdaQuery(ZzTeacher.class).eq(ZzTeacher::getTel, loginForm.getUsername()).last("limit 1"));
                if (null != zzTeacher) {
                    if (CommonEnums.NO == CommonEnums.getCode(zzTeacher.getState())) {
                        throw new DisabledException("老师状态有误,不能使用");
                    }
                    //验证学校
                    ZzSchool zzSchool = zzSchoolMapper.selectById(zzTeacher.getSchoolId());
                    if (null == zzSchool) {
                        throw new DisabledException("对应学校不存在");
                    }
                    if (zzSchool.getState() == 2) {
                        throw new DisabledException("当前校区已停用");
                    }
                    SysUser user = new SysUser();
                    user.setId(zzTeacher.getId());
                    user.setUserName(zzTeacher.getTel());
                    user.setNickName(zzTeacher.getName());
                    user.setPassword(zzTeacher.getPwd());
                    user.setUserType(UserTypeEnumns.DEVICE_TEACHER.getCode());
                    if (null == customPasswordService) {
                        passwordService.validate(user, loginForm.getPassword());
                    } else {
                        customPasswordService.validate(user, loginForm);
                    }
                    return createLoginUser(user, Sets.newHashSet());
                }
            }
        } catch (Exception e) {
            throw e;
        }
        throw new UsernameNotFoundException("用户或密码错误");
    }

    public UserDetails createLoginUser(SysUser user, HashSet<GrantedAuthority> authorities) {
        return new LoginUser(user.getId(), user.getDeptId(), user, authorities);
    }
}
